home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / programming / assembly / ellipseasm.lha / ellipse.code / text0000.txt < prev   
Encoding:
Text File  |  1989-10-24  |  7.3 KB  |  247 lines

  1. >From jackm@devvax.JPL.NASA.GOV Fri Jan  8 11:21:09 1988
  2. Path: leah!uwmcsd1!bbn!oberon!cit-vax!elroy!devvax!jackm
  3. From: jackm@devvax.JPL.NASA.GOV (Jack Morrison)
  4. Newsgroups: comp.graphics
  5. Subject: Re: circles with non-unity aspect ratio (Ellipses! LONG, w/code)
  6. Keywords: circles, ellipses, algorithms
  7. Message-ID: <971@devvax.JPL.NASA.GOV>
  8. Date: 8 Jan 88 16:21:09 GMT
  9. Reply-To: jackm@devvax.JPL.NASA.GOV (Jack Morrison)
  10. Organization: Jet Propulsion Laboratory, Pasadena, CA.
  11. Lines: 232
  12.  
  13. A few requests for ellipses have prompted me to include this code. It
  14. draws ellipses (including circles, of course) of varying line width
  15. on a SUN bitmap display. (It's part of a paint-type program). I don't
  16. know how this compares to the earlier posting of an ellipse algorithm,
  17. but it's fairly fast.
  18.  
  19. Enjoy or flame....
  20.  
  21. =====================================================================
  22.  
  23. /***********************************************/
  24. /* gred_ellipse.c - draw ellipses        *
  25. /* algorithm from IEEE CG&A Sept 1984 p.24     *
  26. /***********************************************/
  27. #include <stdio.h>
  28. #include <sunwindow/window_hs.h>
  29.  
  30. gred_ellipse (cx, cy, radius_x, radius_y, line_width, pw, pattern_pr)
  31. int               cx, cy;
  32. int               radius_x, radius_y;
  33. int            line_width;
  34. struct pixwin         *pw;
  35. struct pixrect         *pattern_pr;
  36. {
  37.     struct pixrect     *pr;
  38.     int            inner_radius_x;
  39.     int            inner_radius_y;
  40.     int            outer_radius_x;
  41.     int            outer_radius_y;
  42.  
  43. /*******************************************************************/
  44. /* Calculate the inner, outer radiuses of the ellipse              */
  45. /*******************************************************************/
  46.     /* if one pixel wide, radiuses are same */
  47.     if (line_width < 2)
  48.     {
  49.     inner_radius_x = outer_radius_x = radius_x;
  50.     inner_radius_y = outer_radius_y = radius_y;
  51.     }
  52.     else
  53.     {
  54.     outer_radius_x = radius_x + (line_width >> 1);
  55.     outer_radius_y = radius_y + (line_width >> 1);
  56.     inner_radius_x = outer_radius_x - line_width + 1;
  57.     inner_radius_y = outer_radius_y - line_width + 1;
  58.     }
  59.  
  60. /*******************************************************************/
  61. /* Create a pixrect to build the ellipse in.                       */
  62. /*******************************************************************/
  63.     pr = mem_create ((outer_radius_x << 1) + 1, (outer_radius_y << 1) + 1, 1);
  64.     /* now clear it */
  65.     pr_rop (pr,    0, 0, pr -> pr_size.x, pr -> pr_size.y,
  66.         PIX_CLR, (struct pixrect *) 0, 0, 0);
  67.  
  68. /*******************************************************************/
  69. /* If the inner_radius > 0 then outline the inner edge.            */
  70. /* Then if the outer radius of the ellipse is > than the inner     */
  71. /* radius, call the fill ellipse routine with the outer radius.    */
  72. /*******************************************************************/
  73.     if ((inner_radius_x > 0)
  74.             && (inner_radius_y > 0))
  75.         outline_ellipse (pr, outer_radius_x, outer_radius_y, 
  76.         inner_radius_x, inner_radius_y);
  77.  
  78.     if (line_width >=  2)
  79.     fill_ellipse(pr, outer_radius_x, outer_radius_y, 
  80.         outer_radius_x, outer_radius_y);
  81.     
  82. /*******************************************************************/
  83. /* Now write the ellipse out to the window.                        */
  84. /*******************************************************************/
  85.     inner_radius_x = inner_radius_y = 0;    /* normal source offset */
  86.     if ((cx -= outer_radius_x) < 0)    /* ellipse extends beyond left edge? */
  87.     {
  88.     inner_radius_x = -cx;
  89.     cx = 0;
  90.     }
  91.     if ((cy -= outer_radius_y) < 0)    /* above top edge? */
  92.     {
  93.         inner_radius_y = -cy;
  94.     cy = 0;
  95.     }
  96.  
  97.     if (pattern_pr == NULL)
  98.         pw_write (pw, cx, cy, pr->pr_size.x-inner_radius_x, pr->pr_size.y-inner_radius_y,
  99.         PIX_SRC ^ PIX_DST, pr, inner_radius_x, inner_radius_y);
  100.     else
  101.     pw_stencil (pw, cx, cy, pr -> pr_size.x, pr -> pr_size.y, 
  102.         PIX_SRC, pr, inner_radius_x, inner_radius_y, pattern_pr, 0, 0);
  103.  
  104.     pr_destroy (pr);
  105. }
  106.  
  107.  
  108. /* draw ellipse incrementally */
  109. static outline_ellipse (pr, center_x, center_y, rx, ry)
  110. struct pixrect *pr;
  111. int    center_x, center_y;
  112. int    rx, ry;
  113. {
  114.     /* intermediate terms to speed up loop */
  115.     long t1 = rx*rx, t2 = t1<<1, t3 = t2<<1;
  116.     long t4 = ry*ry, t5 = t4<<1, t6 = t5<<1;
  117.     long t7 = rx*t5, t8 = t7<<1, t9 = 0L;
  118.     long d1 = t2 - t7 + (t4>>1);    /* error terms */
  119.     long d2 = (t1>>1) - t8 + t5;
  120.  
  121.     register int x = rx, y = 0;    /* ellipse points */
  122.  
  123.     while (d2 < 0)            /* til slope = -1 */
  124.     {
  125.         /* draw 4 points using symmetry */
  126.             pr_put (pr, center_x + x, center_y + y, 1);
  127.             pr_put (pr, center_x + x, center_y - y, 1);
  128.             pr_put (pr, center_x - x, center_y + y, 1);
  129.             pr_put (pr, center_x - x, center_y - y, 1);
  130.  
  131.         y++;        /* always move up here */
  132.         t9 += t3;    
  133.         if (d1 < 0)    /* move straight up */
  134.         {
  135.             d1 += t9 + t2;
  136.             d2 += t9;
  137.         }
  138.         else        /* move up and left */
  139.         {
  140.             x--;
  141.             t8 -= t6;
  142.             d1 += t9 + t2 - t8;
  143.             d2 += t9 + t5 - t8;
  144.         }
  145.     }
  146.  
  147.     do                 /* rest of top right quadrant */
  148.     {
  149.         /* draw 4 points using symmetry */
  150.             pr_put (pr, center_x + x, center_y + y, 1);
  151.             pr_put (pr, center_x + x, center_y - y, 1);
  152.             pr_put (pr, center_x - x, center_y + y, 1);
  153.             pr_put (pr, center_x - x, center_y - y, 1);
  154.  
  155.         x--;        /* always move left here */
  156.         t8 -= t6;    
  157.         if (d2 < 0)    /* move up and left */
  158.         {
  159.             y++;
  160.             t9 += t3;
  161.             d2 += t9 + t5 - t8;
  162.         }
  163.         else        /* move straight left */
  164.             d2 += t5 - t8;
  165.     } while (x>=0);
  166. }
  167.  
  168.  
  169. static fill_ellipse (pr, center_x, center_y, rx, ry)
  170. struct pixrect *pr;
  171. int    center_x, center_y;
  172. int    rx, ry;
  173. {
  174.     long t1 = rx*rx, t2 = t1<<1, t3 = t2<<1;
  175.     long t4 = ry*ry, t5 = t4<<1, t6 = t5<<1;
  176.     long t7 = rx*t5, t8 = t7<<1, t9 = 0;
  177.     long d1 = t2 - t7 + (t4>>1);    /* error terms */
  178.     long d2 = (t1>>1) - t8 + t5;
  179.     register int x = rx, y = 0;    /* ellipse points */
  180.         register int t;            /* used in fill operation */
  181.     int wid;            /* width of fill */
  182.  
  183.     while (d2 < 0)            /* til slope = -1 */
  184.     {
  185.          /* fill in leftward to inner ellipse */
  186.             for (t=x; (!pr_get(pr, center_x+t, center_y+y)) && t; t--);
  187.         wid = x - t + 1;
  188.         pr_rop (pr, center_x+t, center_y+y, wid, 1,
  189.             PIX_SET | PIX_DONTCLIP, NULL, 0, 0);
  190.         pr_rop (pr, center_x-x, center_y+y, wid, 1,
  191.             PIX_SET | PIX_DONTCLIP, NULL, 0, 0);
  192.         pr_rop (pr, center_x+t, center_y-y, wid, 1,
  193.             PIX_SET | PIX_DONTCLIP, NULL, 0, 0);
  194.         pr_rop (pr, center_x-x, center_y-y, wid, 1,
  195.             PIX_SET | PIX_DONTCLIP, NULL, 0, 0);
  196.  
  197.         y++;        /* always move up here */
  198.         t9 += t3;    
  199.         if (d1 < 0)    /* move straight up */
  200.         {
  201.             d1 += t9 + t2;
  202.             d2 += t9;
  203.         }
  204.         else        /* move up and left */
  205.         {
  206.             x--;
  207.             t8 -= t6;
  208.             d1 += t9 + t2 - t8;
  209.             d2 += t9 + t5 - t8;
  210.         }
  211.     }
  212.  
  213.     do                 /* rest of top right quadrant */
  214.     {
  215.         /* fill in downward to inner ellipse */
  216.             for (t=y; (!pr_get(pr, center_x+x, center_y+t)) && t; t--);
  217.         wid = y - t + 1;
  218.         pr_rop (pr, center_x+x, center_y+t, 1, wid,
  219.             PIX_SET | PIX_DONTCLIP, NULL, 0, 0);
  220.         pr_rop (pr, center_x+x, center_y-y, 1, wid,
  221.             PIX_SET | PIX_DONTCLIP, NULL, 0, 0);
  222.         pr_rop (pr, center_x-x, center_y+t, 1, wid,
  223.             PIX_SET | PIX_DONTCLIP, NULL, 0, 0);
  224.         pr_rop (pr, center_x-x, center_y-y, 1, wid,
  225.             PIX_SET | PIX_DONTCLIP, NULL, 0, 0);
  226.  
  227.         x--;        /* always move left here */
  228.         t8 -= t6;    
  229.         if (d2 < 0)    /* move up and left */
  230.         {
  231.             y++;
  232.             t9 += t3;
  233.             d2 += t9 + t5 - t8;
  234.         }
  235.         else        /* move straight left */
  236.         {
  237.             d2 += t5 - t8;
  238.         }
  239.     } while (x>=0);
  240. }
  241. -- 
  242. Jack C. Morrison    Jet Propulsion Laboratory
  243. (818)354-1463        jackm@jpl-devvax.jpl.nasa.gov
  244. "The paycheck is part government property, but the opinions are all mine."
  245.  
  246.  
  247.